# -*- coding: utf-8 -*-
import os, stat, errno
import fuse
import sys
from fuse import Fuse, Stat
from inode import Inode
import time

class Simple(Fuse):
	def __init__(self, *argv, **kw):
		fuse.Fuse.__init__(self, *argv, **kw)
		
		self.__fd = None
		self.__loglvl = None
		
		self.__table = {}
		
	def open_log(self, filename = None, loglvl = 1):
		if filename == None:
			self.__fd = sys.stdout
		else:
			self.__fd = open(filename, 'w')
		self.__loglvl = loglvl
	
	def debug1(self, format, *others):
		if (self.__fd != None and self.__loglvl != None):
			if self.__loglvl < 1 : return
			self.__fd.write((format + '\n') % others)
		self.__fd.flush()
	
	def debug2(self, format, *others):
		if (self.__fd != None and self.__loglvl != None):
			if self.__loglvl < 2 : return
			self.__fd.write((format + '\n') % others)
		self.__fd.flush()
	
	def debug3(self, format, *others):
		if (self.__fd != None and self.__loglvl != None):
			if self.__loglvl < 3 : return
			self.__fd.write((format + '\n') % others)
		self.__fd.flush()
		
	def getattr(self, path):
		self.debug1('Getattr-Entry: Path: %s', path)
		if (path == '/'):
			st = Stat()
			st.st_mode = stat.S_IFDIR | 0755
			st.st_nlink = 2
		elif (self.__table.has_key(path)):
			st = self.__table[path].metadata
		else:
			st = -errno.ENOENT
		self.debug1('Getattr-Exit: St: %s', st)
		return st
	
	def mknod(self, path, mode, dev):
		self.debug1('Mknod-Entry: Path: %s, Mode: %s', path, mode)
		new_time = time.time()
		inode = Inode()
		p_father = path.rpartition('/')[0]
		if (p_father != ''):
			i_father = self.__table[p_father]
			i_father.metadata.st_mtime = new_time
			i_father.metadata.st_ctime = new_time
		
		inode.metadata.st_nlink = 1
		inode.metadata.st_dev = dev
		inode.metadata.st_mode = mode
		inode.metadata.st_atime = new_time
		inode.metadata.st_mtime = new_time
		inode.metadata.st_ctime = new_time
		inode.metadata.st_uid = os.getuid()
		inode.metadata.st_gid = os.getgid()
		
		self.__table[path] = inode
		self.debug1('Mknod-Exit: %s', 0)
		return 0
	
	def readdir(self, path, offset):
		self.debug1('Readdir-Entry: Path: %s, Offset: %s', path, offset)
		result = []
		if path != "/":
			path = path + "/"
		list_paths = self.__table.keys()
		for i in list_paths:
			if i.startswith (path):
				name = i.partition (path)[2]
				if (name.find('/') == -1):
					result.append(name)
					
		self.debug1('Readdir-Exit: Collected list of path\'s')
		for r in result:
			yield fuse.Direntry(r)
	
	def write(self, path, buff, offset):
		self.debug1('Write-Entry: Path: %s, Buff: %s, Offset: %s', path, buff[0:len(buff)-1], offset)
		size = len(buff)
		new_time = time.time()
		inode = self.__table[path]

		inode.metadata.st_mtime = new_time
		inode.metadata.st_atime = new_time
		inode.metadata.st_size = size + offset

		inode.data = inode.data + buff
		self.debug1('Write-Exit: Size: %s', size)
		return size

	def read (self, path, length, offset):
		self.debug1('Read-Entry: Path: %s, Lenght: %s, Offset: %s', path, length, offset)
		new_time = time.time()
		inode = self.__table[path]
		inode.metadata.st_atime = new_time
		data = inode.data
		buff = data[offset : length + offset - 1]
		self.debug1('Read-Exit: Buff: %s', buff)
		return buff
		